package fuzion24.device.vulnerability.test.adapter;

import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.nowsecure.android.vts.R;

import org.json.JSONArray;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import fuzion24.device.vulnerability.test.VulnerabilityDescriptor;
import fuzion24.device.vulnerability.test.VulnerabilityTestResult;
import fuzion24.device.vulnerability.test.adapter.viewholder.RecyclerItemViewHolder;
import fuzion24.device.vulnerability.vulnerabilities.helper.BinaryAssets;

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final String TAG = "RecycleAdapter";
    private List<Pair<VulnerabilityTestResult, VulnerabilityDescriptor>> mResults;
    private Context mContext;

    private static final SimpleDateFormat mSDF = new SimpleDateFormat("MM/dd/yyyy", Locale.US);


    public RecyclerAdapter(Context context, List<VulnerabilityTestResult> itemList) {
        this.mContext = context;
        this.mResults = buildResultDescriptionMap(context, itemList);
    }


    private static List<Pair<VulnerabilityTestResult, VulnerabilityDescriptor>> buildResultDescriptionMap(Context context, List<VulnerabilityTestResult> itemList){
        List<Pair<VulnerabilityTestResult, VulnerabilityDescriptor>> res = new ArrayList<>();

        try {
            Map<String, VulnerabilityDescriptor> vMap = VulnerabilityDescriptor.getParsedVulnMap(context);

            for (VulnerabilityTestResult vtr : itemList) {
                String cveOrId = vtr.getCVEorID();
                VulnerabilityDescriptor vd = vMap.get(cveOrId);
                if(vd == null){
                    Log.d(TAG, cveOrId + " has a null vulnerability descriptor");
                }
                res.add(Pair.create(vtr, vd));
            }

            Collections.sort(res, new Comparator<Pair<VulnerabilityTestResult, VulnerabilityDescriptor>>() {
                private final static int leftFirst = -1;
                private final static int rightFirst = 1;
                private final static int areEqual = 0;

                @Override
                public int compare(Pair<VulnerabilityTestResult, VulnerabilityDescriptor> lhs, Pair<VulnerabilityTestResult, VulnerabilityDescriptor> rhs) {
                    VulnerabilityDescriptor lhDesc = lhs.second;
                    VulnerabilityDescriptor rhDesc = rhs.second;

                    boolean rIsNewer = lhDesc.getCVEDate().before(rhDesc.getCVEDate());
                    boolean sameDate = lhDesc.getCVEDate().equals(rhDesc.getCVEDate());
                    boolean lVuln  = lhs.first.getException() == null && lhs.first.isVulnerable();
                    boolean rVuln  = rhs.first.getException() == null && rhs.first.isVulnerable();

                     if(lVuln && !rVuln){
                        return leftFirst;
                     }else if(!lVuln && rVuln){
                        return rightFirst;
                     }else if(sameDate) {
                         return areEqual;
                     } else {
                        return rIsNewer ? rightFirst : leftFirst;
                     }
                }
            });

        }catch(Exception e){
            e.printStackTrace();
        }
        return res;

    }


    public void updateResults(List<VulnerabilityTestResult> itemList){
        mResults = buildResultDescriptionMap(mContext, itemList);
        notifyDataSetChanged();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        View view = LayoutInflater.from(context).inflate(R.layout.vulnerability_layout, parent, false);

        return RecyclerItemViewHolder.newInstance(view);
    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        RecyclerItemViewHolder holder = (RecyclerItemViewHolder) viewHolder;
        Pair<VulnerabilityTestResult, VulnerabilityDescriptor> item = mResults.get(position);

        VulnerabilityTestResult vulnRes = item.first;
        VulnerabilityDescriptor vulnDesc = item.second;

        holder.setItemTestName(vulnRes.getCVEorID());


        if (vulnRes.getException() != null) {
            holder.setItemTestResult(mContext.getString(R.string.error_test, vulnRes.getException().getMessage()));
            holder.setItemTestResultColor(mContext.getResources().getColor(R.color.orange));
        } else {
            if (vulnRes.getResult()) {
                holder.setItemTestResultColor(mContext.getResources().getColor(R.color.red));
                holder.setItemTestResult(mContext.getString(R.string.test_result_failure));
            } else {
                holder.setItemTestResultColor(mContext.getResources().getColor(R.color.green));
                holder.setItemTestResult(mContext.getString(R.string.test_result_success));
            }
        }

        holder.setItemTestResultDescription(vulnDesc.getDescription());
        holder.setButtonShowDetailsClickListner(mContext,
                vulnRes.getCVEorID(),
                vulnDesc.getAltNames(),
                vulnDesc.getDescription(),
                vulnDesc.getImpact(),
                vulnDesc.getExternalLinks(),
                vulnDesc.getPatches(),
                vulnDesc.getCVSSV2Score(),
                mSDF.format(vulnDesc.getCVEDate()));
    }

    @Override
    public int getItemCount() {
        return mResults == null ? 0 : mResults.size();
    }

}
